package com.fish.yssb.db;


import android.support.annotation.NonNull;
import android.util.Log;

import com.fish.yssb.db.bean.BaseInfoTable;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import io.realm.DynamicRealm;
import io.realm.FieldAttribute;
import io.realm.RealmMigration;
import io.realm.RealmObject;
import io.realm.RealmObjectSchema;
import io.realm.RealmSchema;


public class CustomMigration implements RealmMigration {
    @Override
    public void migrate(final DynamicRealm realm, long oldVersion, long newVersion) {
        try{
            //获取可编辑的图表schema
            if(oldVersion <23)
            {
                createData(realm, new BaseInfoTable());
            }
            if ( oldVersion == newVersion ) {
                //更新数据库结构（比如增加字段）
                updateFields( realm );
            }
        }catch (Exception ex)
        {
            ex.printStackTrace();
        }
  }

    @SuppressWarnings( "ConstantConditions" )
    private void updateFields ( @NonNull DynamicRealm realm ) {
        try {

            updateData(realm, new BaseInfoTable());

        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    private void createData(@NonNull DynamicRealm realm, RealmObject table)
    {
        RealmSchema schema = realm.getSchema();
        schema.create(table.getClass().getSimpleName())
//        schema.create("TimeInfo6")
                .addField("name", String.class)
                .addField("age", String.class);
    }

    private void updateData(@NonNull DynamicRealm realm, RealmObject table)
    {
        Map<String, String> filedMap = new HashMap<>();
        //set集合存放的是realm数据库的字段集
        Set<String> s = realm.getSchema().get( table.getClass().getSimpleName() ).getFieldNames();
        for ( String param : s ) {
            Log.e( "数据库字段Set", param );
            filedMap.put( param, param );
        }
        //反射时，会反射出这两项
//        filedMap.put( "serialVersionUID", "serialVersionUID" );
//        filedMap.put( "$change", "$change" );

        RealmSchema schema = realm.getSchema();
        RealmObjectSchema personSchema = schema.get( table.getClass().getSimpleName() );
        if ( personSchema != null ) {
            //反射，是获取实体类的所有私有属性（即我们更改表结构后的所有字段名）
            Field[] changeFields = table.getClass().getDeclaredFields();
            if ( filedMap.size() > changeFields.length ) {
                //减字段
                Map<String, String> changeFieldMap = new HashMap<>();
                for ( Field changeField : changeFields ) {
                    String changeName = changeField.getName();
                    //得到更改后表的字段
                    changeFieldMap.put( changeName, changeName );
                }
                for ( String field : filedMap.keySet() ) {
                    if ( changeFieldMap.containsKey( field ) ) {
                        Log.e( "数据库字段", field + "该字段还存在于表中" );
                    } else {
                        Log.e( "数据库字段", field + "该字段已移除" );
                        personSchema.removeField( field );
                    }
                }
            } else {
                //加字段
                for ( Field changeField : changeFields ) {
                    String changeName = changeField.getName();
                    if ( filedMap.containsKey( changeName ) ) {
                        //假如字段名已存在就进行下次循环
                        Log.e( "数据库字段", changeName + "该字段已存在" );
                    } else {
                        //不存在，就放到map中，并且给表添加字段
                        filedMap.put( changeName, changeName );
                        Log.e( "数据库字段", changeName + "该字段已添加到表中" );
                        //根据属性的类型给表增加字段
                        String type = changeField.getType().toString();
                        if ( type.equals( "class java.lang.String" ) ) {
                            //使用FieldAttribute.REQUIRED，必须再entity此字段加注解@Required
                            personSchema.addField( changeName, String.class );
//                            personSchema.addField( changeName, String.class, FieldAttribute.REQUIRED );
                            continue;
                        }
                        if ( type.equals( "int" ) ) {
                            //两种方式实现一致，并且不用加注解@Required
//                            personSchema.addField( changeName, int.class );
                            personSchema.addField( changeName, int.class, FieldAttribute.REQUIRED );
                            continue;
                        }
                        if ( type.equals( "class java.lang.Long" ) ) {
                            personSchema.addField( changeName, long.class, FieldAttribute.REQUIRED );
                            //Long修饰词，不能使用此方法，会造成io.realm.exceptions.RealmMigrationNeededException错误
                            // Native Method提示出错
                            //personSchema.addField( changeName, long.class );
                            continue;
                        }
                        if ( type.equals( "boolean" ) ) {
                            personSchema.addField( changeName, Boolean.class, FieldAttribute.REQUIRED );
                            //Boolean修饰词，不能使用此方法，会造成io.realm.exceptions.RealmMigrationNeededException错误
                            // Native Method提示出错
//                            personSchema.addField( changeName, Boolean.class );
                        } else {
                            Log.i( "数据库增加字段失败", "数据库出错" );
                        }
                    }
                }
            }
        } else {
            Log.e( "数据库无法更新", "personSchema为空，可能是没有实体类存在" );
        }
    }
}

